package cn.diandiandidi.sm.userdata;

import java.util.Iterator;
import java.util.UUID;
import java.util.Vector;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import cn.diandiandidi.sm.system.SmSystem;

public class UserDataRecord {

	private boolean m_Valid;
	private static final String RECORD_TITLE_STR = "title";
	private static final String RECORD_BELONG_TO_CATEGORY_STR = "category";
	private static final String RECORD_ITEMS_STR = "items";
	private static final String RECORD_ITEM_TYPE_STR = "type";
	private static final String RECORD_ITEM_NAME_STR = "name";
	private static final String RECORD_ITEM_NAME_VALUE_STR = "name_value";
	private static final String RECORD_ITEM_NUMBER_UNIT_VALUE_STR = "unit";
	private static final String RECORD_ITEM_NUMBER_GROUP_RULE_STR = "group_rule";
	private static final String RECORD_ITEM_NUMBER_SEPARATOR_STR = "separator";
	private static final String RECORD_ITEM_IMAGE_PATH_STR = "image";
	private static final String RECORD_ITEM_SOUND_PATH_STR = "sound";
	
	public UserDataRecord(JSONObject jsonObject) throws JSONException {
		mIconType = jsonObject.getInt(UserDatabase.DATABASE_ITEM_ICON_TYPE_STR);
		mIconData = jsonObject.getString(UserDatabase.DATABASE_ITEM_ICON_DATA_STR);
		mID = UUID.fromString(jsonObject.getString(UserDatabase.DATABASE_ITEM_ID_STR));
		if(jsonObject.has(UserDatabase.DATABASE_ITEM_VALID_STR)) {
			m_Valid = jsonObject.getBoolean(UserDatabase.DATABASE_ITEM_VALID_STR);
		}else m_Valid = true;
		mTitle = jsonObject.getString(RECORD_TITLE_STR);
		mCategoryID = UUID.fromString(jsonObject.getString(RECORD_BELONG_TO_CATEGORY_STR));
		//load items of record
		JSONArray itemsArray = jsonObject.getJSONArray(RECORD_ITEMS_STR);
		mItems = new Vector<RecordItem>();
		for (int i = 0; i < itemsArray.length(); ++i) {
			Bundle bundle = new Bundle();
			JSONObject itemObject = itemsArray.getJSONObject(i);
			int itemType = getItemTypeIndex(itemObject.getString(RECORD_ITEM_TYPE_STR));
			switch(itemType) {
			case RECORD_ITEM_TYPE_TEXT:
				bundle.putString(RECORD_ITEM_NAME_STR, itemObject.getString(RECORD_ITEM_NAME_STR));
				bundle.putString(RECORD_ITEM_NAME_VALUE_STR, itemObject.getString(RECORD_ITEM_NAME_VALUE_STR));
				mItems.add(new RecordItem(RECORD_ITEM_TYPE_TEXT, bundle));
				break;
			case RECORD_ITEM_TYPE_NUMBER:
				bundle.putString(RECORD_ITEM_NAME_STR, itemObject.getString(RECORD_ITEM_NAME_STR));
				bundle.putString(RECORD_ITEM_NAME_VALUE_STR, itemObject.getString(RECORD_ITEM_NAME_VALUE_STR));
				if(jsonObject.has(RECORD_ITEM_NUMBER_UNIT_VALUE_STR)) bundle.putString(RECORD_ITEM_NUMBER_UNIT_VALUE_STR, itemObject.getString(RECORD_ITEM_NUMBER_UNIT_VALUE_STR));
				if(jsonObject.has(RECORD_ITEM_NUMBER_GROUP_RULE_STR)) bundle.putString(RECORD_ITEM_NUMBER_GROUP_RULE_STR, itemObject.getString(RECORD_ITEM_NUMBER_GROUP_RULE_STR));
				if(jsonObject.has(RECORD_ITEM_NUMBER_SEPARATOR_STR)) bundle.putString(RECORD_ITEM_NUMBER_SEPARATOR_STR, itemObject.getString(RECORD_ITEM_NUMBER_SEPARATOR_STR));
				mItems.add(new RecordItem(RECORD_ITEM_TYPE_NUMBER, bundle));
				break;
			case RECORD_ITEM_TYPE_IMAGE:
				bundle.putString(RECORD_ITEM_NAME_STR, itemObject.getString(RECORD_ITEM_NAME_STR));
				bundle.putString(RECORD_ITEM_NAME_VALUE_STR, itemObject.getString(RECORD_ITEM_NAME_VALUE_STR));
				bundle.putString(RECORD_ITEM_IMAGE_PATH_STR, itemObject.getString(RECORD_ITEM_IMAGE_PATH_STR));
				mItems.add(new RecordItem(RECORD_ITEM_TYPE_IMAGE, bundle));
				break;
			case RECORD_ITEM_TYPE_SOUND:
				bundle.putString(RECORD_ITEM_NAME_STR, itemObject.getString(RECORD_ITEM_NAME_STR));
				bundle.putString(RECORD_ITEM_NAME_VALUE_STR, itemObject.getString(RECORD_ITEM_NAME_VALUE_STR));
				bundle.putString(RECORD_ITEM_SOUND_PATH_STR, itemObject.getString(RECORD_ITEM_SOUND_PATH_STR));
				mItems.add(new RecordItem(RECORD_ITEM_TYPE_SOUND, bundle));
				break;
			case RECORD_ITEM_TYPE_SEPARATOR:
				bundle.putString(RECORD_ITEM_NAME_STR, itemObject.getString(RECORD_ITEM_NAME_STR));
				bundle.putString(RECORD_ITEM_NAME_VALUE_STR, itemObject.getString(RECORD_ITEM_NAME_VALUE_STR));
				bundle.putString(RECORD_ITEM_IMAGE_PATH_STR, itemObject.getString(RECORD_ITEM_IMAGE_PATH_STR));
				mItems.add(new RecordItem(RECORD_ITEM_TYPE_SEPARATOR, bundle));
				break;
			}			
		}
	}
	
	public JSONObject toJsonObject() {
		JSONObject recordObject= new JSONObject();		
		try {
			recordObject.put(UserDatabase.DATABASE_DATA_TYPE_STR, UserDatabase.DATABASE_ITEM_TYPE_RECORD);
			recordObject.put(UserDatabase.DATABASE_ITEM_ID_STR, mID.toString());
			recordObject.put(UserDatabase.DATABASE_ITEM_ICON_TYPE_STR, mIconType);
			recordObject.put(UserDatabase.DATABASE_ITEM_ICON_DATA_STR, mIconData);
			recordObject.put(RECORD_TITLE_STR, mTitle);
			recordObject.put(RECORD_BELONG_TO_CATEGORY_STR, mCategoryID.toString());
			if(m_Valid==false) recordObject.put(UserDatabase.DATABASE_ITEM_VALID_STR, m_Valid);
			
			JSONArray recordItems = new JSONArray();
			Iterator<RecordItem> i = mItems.iterator();
			for (; i.hasNext(); ) {
				RecordItem item = i.next();
				JSONObject itemObject = new JSONObject();				
				switch(item.type) {
				case RECORD_ITEM_TYPE_TEXT:
					itemObject.put(RECORD_ITEM_TYPE_STR, getItemTypeStr(RECORD_ITEM_TYPE_TEXT));
					itemObject.put(RECORD_ITEM_NAME_STR, item.data.get(RECORD_ITEM_NAME_STR));
					itemObject.put(RECORD_ITEM_NAME_VALUE_STR, item.data.get(RECORD_ITEM_NAME_VALUE_STR));					
					break;
				case RECORD_ITEM_TYPE_NUMBER:
					itemObject.put(RECORD_ITEM_TYPE_STR, getItemTypeStr(RECORD_ITEM_TYPE_NUMBER));
					itemObject.put(RECORD_ITEM_NAME_STR, item.data.get(RECORD_ITEM_NAME_STR));
					itemObject.put(RECORD_ITEM_NAME_VALUE_STR, item.data.get(RECORD_ITEM_NAME_VALUE_STR));					
					itemObject.put(RECORD_ITEM_NUMBER_UNIT_VALUE_STR, item.data.get(RECORD_ITEM_NUMBER_UNIT_VALUE_STR));
					itemObject.put(RECORD_ITEM_NUMBER_GROUP_RULE_STR, item.data.get(RECORD_ITEM_NUMBER_GROUP_RULE_STR));
					itemObject.put(RECORD_ITEM_NUMBER_SEPARATOR_STR, item.data.get(RECORD_ITEM_NUMBER_SEPARATOR_STR));										
					break;
				case RECORD_ITEM_TYPE_IMAGE:
					itemObject.put(RECORD_ITEM_TYPE_STR, getItemTypeStr(RECORD_ITEM_TYPE_IMAGE));
					itemObject.put(RECORD_ITEM_NAME_STR, item.data.get(RECORD_ITEM_NAME_STR));
					itemObject.put(RECORD_ITEM_NAME_VALUE_STR, item.data.get(RECORD_ITEM_NAME_VALUE_STR));					
					itemObject.put(RECORD_ITEM_IMAGE_PATH_STR, item.data.get(RECORD_ITEM_IMAGE_PATH_STR));					
					break;
				case RECORD_ITEM_TYPE_SOUND:
					itemObject.put(RECORD_ITEM_TYPE_STR, getItemTypeStr(RECORD_ITEM_TYPE_SOUND));
					itemObject.put(RECORD_ITEM_NAME_STR, item.data.get(RECORD_ITEM_NAME_STR));
					itemObject.put(RECORD_ITEM_NAME_VALUE_STR, item.data.get(RECORD_ITEM_NAME_VALUE_STR));					
					itemObject.put(RECORD_ITEM_SOUND_PATH_STR, item.data.get(RECORD_ITEM_SOUND_PATH_STR));
					break;
				case RECORD_ITEM_TYPE_SEPARATOR:
					itemObject.put(RECORD_ITEM_TYPE_STR, getItemTypeStr(RECORD_ITEM_TYPE_SEPARATOR));
					itemObject.put(RECORD_ITEM_NAME_STR, item.data.get(RECORD_ITEM_NAME_STR));
					itemObject.put(RECORD_ITEM_NAME_VALUE_STR, item.data.get(RECORD_ITEM_NAME_VALUE_STR));					
					itemObject.put(RECORD_ITEM_IMAGE_PATH_STR, item.data.get(RECORD_ITEM_IMAGE_PATH_STR));
					break;
				}
				recordItems.put(itemObject);
			}
			recordObject.put(RECORD_ITEMS_STR, recordItems);
			return recordObject;
		} catch (JSONException e) {
			return null;
		}			
	}
	
	public static final int RECORD_ITEM_TYPE_TEXT=0;
	public static final int RECORD_ITEM_TYPE_NUMBER=1;
	public static final int RECORD_ITEM_TYPE_IMAGE=2;
	public static final int RECORD_ITEM_TYPE_SOUND=3;
	public static final int RECORD_ITEM_TYPE_SEPARATOR=4;	
	public static final String[] mAllItemType= {
			"Text","Number","Image","Sound","Separator"				
	};
	private int getItemTypeIndex(String typeStr) {		
		for(int i = 0; i < mAllItemType.length; ++i) {
			if(mAllItemType[i].equals(typeStr)) return i;
		}
		return -1;
	}
	private String getItemTypeStr(int index) {
		return mAllItemType[index];
	}
	
	public void setTextItem(int index, String textItemName,	String textItemValue) {
		Bundle bundle;
		if(index == -1) {
			bundle = new Bundle();
			bundle.putString(RECORD_ITEM_NAME_STR, textItemName);
			bundle.putString(RECORD_ITEM_NAME_VALUE_STR,  textItemValue);			
			mItems.add(new RecordItem(RECORD_ITEM_TYPE_TEXT, bundle));
		}else {
			if(index >= mItems.size()) return;
			RecordItem item = mItems.get(index);
			item.type = RECORD_ITEM_TYPE_TEXT; 
			bundle = item.data;
			bundle.clear();
			bundle.putString(RECORD_ITEM_NAME_STR, textItemName);
			bundle.putString(RECORD_ITEM_NAME_VALUE_STR,  textItemValue);
		}		
	}
	
	public UserDataRecord(UUID categoryId) {
		mIconType=SmSystem.ICON_DATA_TYPE_RES;
		mIconData=null;
		mID=UUID.randomUUID();
		m_Valid = true;
		mTitle = "";
		mCategoryID = categoryId;
		mItems = new Vector<RecordItem>();		
	}

	@SuppressWarnings("unchecked")
	public UserDataRecord(UserDataRecord other) {
		this.m_Valid = other.m_Valid;
		this.mCategoryID = other.mCategoryID;
		this.mIconData = new String(other.mIconData);
		this.mIconType = other.mIconType;
		this.mID = other.mID;
		this.mTitle = new String(other.mTitle);
		this.mItems = (Vector<RecordItem>) other.mItems.clone();
	}

	public UUID getID() { return mID; }
	
	public UUID getCategoryID() { return mCategoryID; }
	
	private UUID mID;
	private UUID mCategoryID;
	
	public int getIconType() {return mIconType; }

	public String getIconData() {return mIconData;}

	private int mIconType;
	private String mIconData;
	public void setIcon(int iconType, String iconData) {
		mIconType = iconType;
		mIconData = iconData;
	}

	private String mTitle;
	public String getTitle() {return mTitle;}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((mID == null) ? 0 : mID.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		UserDataRecord other = (UserDataRecord) obj;
		if (mID == null) {
			if (other.mID != null)
				return false;
		} else if (!mID.equals(other.mID))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return toJsonObject().toString();
	}
	
	private Vector<RecordItem> mItems;
	private class RecordItem {
		int type;
		Bundle data;		
		public RecordItem(int type, Bundle bundle) {
			this.type = type;
			this.data = bundle;
		}		
	}
	public int getItemCount() {
		return mItems.size();
	}

	public int getItemType(int position) {
		return mItems.get(position).type;
	}

	public String getTextItemName(int position) {
		return mItems.get(position).data.getString(RECORD_ITEM_NAME_STR);
	}

	public String getTextItemNameValue(int position) {
		return mItems.get(position).data.getString(RECORD_ITEM_NAME_VALUE_STR);
	}

	public void setTitle(String titleStr) {
		mTitle = titleStr;
	}

	public void removeItem(int index) {
		mItems.remove(index);
	}

	public void moveItem(int curPos, int newPos) {
		RecordItem item = mItems.remove(curPos);
		mItems.insertElementAt(item, newPos);
	}

	public void setValid(boolean b) {
		m_Valid = b;
	}
	
}
